import re
from rest_framework import serializers

from goods.models import SKU
from orders.models import OrderInfo,OrderGoods
from .models import User
from django_redis import get_redis_connection
from .models import User
from django.core.mail import send_mail
from django.conf import settings
from celery_tasks.email.tasks import send_verify_url
from .models import Address


class RegisterUserSerializer(serializers.ModelSerializer):
    # write_only: 只写,只校验, 不入库, 也不需要返回到前端浏览
    password2 = serializers.CharField(min_length=8, max_length=20, label="确认密码", write_only=True)
    sms_code = serializers.CharField(min_length=6, max_length=6, label="短信验证码", write_only=True)
    allow = serializers.CharField(label="协议", write_only=True)
    token = serializers.CharField(label="jwt口令", read_only=True)

    class Meta:
        model = User
        fields = ("id", "username", "password", "password2", "mobile", "sms_code", "allow", "token")

        read_only_fields = ("id",)

        extra_kwargs = {
            "password": {
                "min_length": 8,
                "max_length": 20,
                "write_only": True
            }
        }

    # 1,单字段校验,allow协议
    def validate_allow(self, value):

        if value != 'true':
            raise serializers.ValidationError("必须同意协议")

        return value

    # 2,校验多字段, 密码, 短信
    def validate(self, attrs):

        # 0,取出手机号,和短信验证码
        sms_code = attrs["sms_code"]
        mobile = attrs["mobile"]

        # 1,校验密码
        if attrs["password"] != attrs["password2"]:
            raise serializers.ValidationError("两次密码不相等")

        # 2,校验短信
        redis_conn = get_redis_connection("code")
        redis_sms_code = redis_conn.get("sms_code_%s" % mobile)

        # 3,判断是否过期
        if not redis_sms_code:
            raise serializers.ValidationError("短信验证码已经过期")

        # 4,校验正确性
        if sms_code != redis_sms_code.decode():
            raise serializers.ValidationError("短信验证码填写错误")

        # 5,返回
        return attrs

    # 3,由于User中没有password2,sms_code,allow,所以需要去除
    def create(self, validated_data):
        # 1,去除不需要的数据
        del validated_data["password2"]
        del validated_data["sms_code"]
        del validated_data["allow"]

        # 2,创建对象
        user = super(RegisterUserSerializer, self).create(validated_data)

        # 2,1密码加密
        user.set_password(validated_data["password"])
        user.save()

        # 设置JWT
        from rest_framework_jwt.settings import api_settings
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        user.token = token

        # 3,返回
        return user


class UserInfoSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ("id", "username", "mobile", "email", "email_active")


class EmailSendSerializer(serializers.Serializer):
    email = serializers.EmailField(label="邮箱")

    def update(self, instance, validated_data):
        # 1,将邮箱设置到用户对象
        email = validated_data["email"]
        instance.email = email
        instance.save()

        # 2,发送邮件
        verify_url = instance.generate_verify_url()
        # send_mail(subject="请你点击验证,来自美多国际商城", message=verify_url,
        #           from_email=settings.EMAIL_FROM,
        #           recipient_list=[email])
        send_verify_url.delay(verify_url, email)  # 使用celery发送

        # 3,返回
        return validated_data


class AddressSerializer(serializers.ModelSerializer):
    province = serializers.StringRelatedField(read_only=True)
    city = serializers.StringRelatedField(read_only=True)
    district = serializers.StringRelatedField(read_only=True)
    province_id = serializers.IntegerField(label="省id")
    city_id = serializers.IntegerField(label="市id")
    district_id = serializers.IntegerField(label="区id")

    class Meta:
        model = Address
        exclude = ("user", "is_deleted", "create_time", "update_time")

    # 重写序列化器的create方法,目的为了补充user
    def create(self, validated_data):
        validated_data["user"] = self.context["request"].user
        return super(AddressSerializer, self).create(validated_data)


class AddressTitleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Address
        fields = ("title",)


class UserBrowerHistorySerializer(serializers.Serializer):
    sku_id = serializers.IntegerField(min_value=1, label="商品编号")

    # 1,单字段校验
    def validate_sku_id(self, value):
        # 1,通过sku_id获取sku对象
        try:
            sku = SKU.objects.get(id=value)
        except Exception as e:
            raise serializers.ValidationError("商品不存在")

        # 2,返回
        return value

    # 2,重写create方法,需要保存记录到redis中
    def create(self, validated_data):
        # 1,获取sku_id
        sku_id = validated_data.get("sku_id")
        user = self.context["request"].user

        # 2,获取redis对象
        redis_conn = get_redis_connection("history")

        # 3,去重
        redis_conn.lrem("history_%s" % user.id, 0, sku_id)

        # 4,存储
        redis_conn.lpush("history_%s" % user.id, sku_id)

        # 5,截取5条
        redis_conn.ltrim("history_%s" % user.id, 0, 4)

        # 6,返回
        return validated_data


class SKUSerializer(serializers.ModelSerializer):
    class Meta:
        model = SKU
        fields = ('default_image_url', 'name')


class OrderGoodsSerializer(serializers.ModelSerializer):
    sku = SKUSerializer(read_only=True)

    class Meta:
        model = OrderGoods
        fields = ('count', 'price', 'sku')


class ListUserOrderSerializer(serializers.ModelSerializer):
    skus = OrderGoodsSerializer(many=True,read_only=True)

    class Meta:
        model = OrderInfo
        fields = ('create_time', 'order_id', 'skus', 'total_amount', 'pay_method', 'status', 'freight')


class ChecKUserViewSerializer(serializers.Serializer):
    text=serializers.CharField(min_length=4,max_length=4,label="图片验证码")
    mobile=serializers.CharField(label="用户名或者编号")
    image_code_id=serializers.UUIDField(label="图片验证码ID")
    def validate(self, attrs):
        text=attrs['text']
        mobile=attrs['mobile']
        redis_conn=get_redis_connection('code')
        real_image_code=redis_conn.get('image_code_%s'%attrs['image_code_id'])
        # 验证图片验证码
        if text.upper() != real_image_code.decode().upper():
            raise serializers.ValidationError('图片验证码错误')
        #根据用户名或者手机号查询用户
        user =None
        try:
            if re.match(r'^[3-9]\d{9}$',mobile):
                user=User.objects.get(mobile=mobile)
            else:
                user=User.objects.get(username=mobile)
        except Exception as e:
            pass
        return {'user':user}
#短信验证
class CheckSmsSerializer(serializers.Serializer):
    mobile=serializers.RegexField(regex=r'^1[3-9]\d{9}$',label='手机号')
    sms_code=serializers.CharField(min_length=6,max_length=6,label='短信验证码')
    def validate(self, attrs):
        mobile=attrs['mobile']
        sms_code=attrs['sms_code']
        #校验短信验证码
        redis_conn=get_redis_connection('code')
        real_sms_code=redis_conn.get('sms_code_%s'%mobile)
        if not real_sms_code:
            raise serializers.ValidationError('短信验证码过期')
        if sms_code != real_sms_code.decode():
            raise serializers.ValidationError('短信验证码错误')
        #根据mobile获取用户
        user =None
        try:
            user=User.objects.get(mobile=mobile)
        except:
            pass
        return {'user':user}
